// translation gamelist, added by regret

/* changelog:
 update 5: remove mangle game name
 update 4: speedup export from mamep.lst
 update 3: add export list (special use)
 update 2: speedup load translist
 update 1: create
*/

#include "burner.h"
#include "seldef.h"

wchar_t transGamelistFile[MAX_PATH];

/* modify by Sho, thanks 800, MAMEPlus! Team */
// optimized by regret, ^^
static int createGamelistFile(const wchar_t* szFile)
{
	wchar_t listName[MAX_PATH];
	swprintf(listName, L"%s", L"mamep.lst");
	FILE* fpLst = _wfopen(listName, L"rt");
	if (fpLst == NULL) {
		swprintf(listName, L"%s", L"config\\mamep.lst");
		fpLst = _wfopen(listName, L"rt");
	}

	FILE* fpIni = _wfopen(szFile, L"wt");
	if (!fpIni) {
		if (fpLst) fclose(fpLst);
		return 1;
	}

	// cache mamep list
	map<wstring, wstring> nameMap;
	if (fpLst) {
		nameMap.clear();

		// get translated game name from MAME Plus! *.lst file
		wchar_t strLine[1024];
		fseek(fpLst, 0, SEEK_SET);
		while (fgetws(strLine, sizearray(strLine), fpLst)) {
			wstring romname = wcstok(strLine, L"\t");
			wstring transname = wcstok(NULL, L"\t");
			nameMap[romname] = transname;
		}
	}

	// write file header
	fwprintf(fpIni, L"// " APP_TITLE L" v%s Local Language GameList File, CodePage: %d\n", appBurnVer, GetACP());
	fwprintf(fpIni, L"// You can edit this file manually. ^^\n");
	fwprintf(fpIni, L"// Format: rom name = game name (equal sign must in two spaces)\n\n");
	fwprintf(fpIni, L"[games]\n");

	unsigned drvCount = BurnGetDrvCount();
	wchar_t gamename[MAX_PATH], transName[MAX_PATH];
	for (unsigned i = 0; i < drvCount; i++) {
		wcscpy(gamename, AtoW(BurnDrvGetTextA(DRV_NAME, i)));
		wcscpy(transName, transGameName(BurnDrvGetTextA(DRV_FULLNAME, i), i));

		if (fpLst) {
			map<wstring, wstring>::iterator iter = nameMap.find(gamename);
			if (iter != nameMap.end()) {
				wcscpy(transName, iter->second.c_str());
			}
		}

		fwprintf(fpIni, L"%s = %s\n", gamename, transName);
	}

	if (fpIni) {
		fclose(fpIni);
	}
	if (fpLst) {
		fclose(fpLst);
		nameMap.clear();
	}

	return 0;
}

map<string, wstring> gamelistMap;
static bool gamelistLoaded = false;

static int initGamelist()
{
	if (gamelistLoaded) {
		return 0;
	}

	gamelistMap.clear();

	// parse gamelist
	FILE* file = _wfopen(transGamelistFile, L"rb");
	if (!file) {
		gamelistLoaded = true; // if didn't find file
		return 1;
	}

	bool utf8File = false;

	// read file header
	unsigned char header[4] = { 0, };
	fread(header, 1, sizeof(header), file);

	// check if it's a UTF-16 file
	if (header[0] == 0xFF && header[1] == 0xFE) {
		fseek(file, 2, SEEK_SET);
	} else {
		// check if it's a UTF-8 file
		if (header[0] == 0xEF && header[1] == 0xBB && header[2] == 0xBF) {
			utf8File = true;
		}
		fclose(file);

		file = _wfopen(transGamelistFile, L"rt");
		if (!file) {
			return 1;
		}
		if (utf8File) {
			fseek(file, 3, SEEK_SET);
		}
	}

	DWORD pos = 0;
	size_t nLen = 0;
	wchar_t s[MAX_PATH];
	wstring line, value;
	string key;

	while (!feof(file)) {
		if (utf8File) {
			char strTemp[MAX_PATH];
			if (fgets(strTemp, sizeof(strTemp), file) == NULL) {
				break;
			}
			wcscpy(s, U8toW(strTemp));
		} else {
			if (fgetws(s, sizeof s, file) == NULL) {
				break;
			}
		}

		if (s[0] == ';' || (s[0] == '/' && s[1] == '/'))
			continue; // skip comment

		// omit last \r\n
		nLen = wcslen(s);
		if (nLen > 1 && s[nLen-2] == '\r') {
			s[nLen-2] = '\0';
		}
		else if (nLen > 1 && s[nLen-1] == '\n') {
			s[nLen-1] = '\0';
		}
		line = s;

		if (line == L"[games]" || line == L"\r\n" || line == L"\n")
			continue;

		size_t pos = line.find(L" = ");
		if (pos == string::npos)
			continue;

		key = WtoA(line.substr(0, pos).c_str()); // get key = rom name
		value = line.substr(pos + 3); // get translation name

		gamelistMap[key] = value;
	}
	fclose(file);

	gamelistLoaded = true;
	return 0;
}

int loadGamelist()
{
	swprintf(commonChoice, L"gamelist.ini");
	if (commonFileDialog(hScrnWnd, false, localiseStringEx(IDS_GAMELIST_SELECT), L"Gamelist file (*.ini)\0*.ini\0\0", L"lang", L"ini")) {
		return 1;
	}
	wcsncpy(transGamelistFile, commonChoice, sizearray(transGamelistFile));

	gamelistLoaded = false;
	initGamelist();

	return 0;
}

int createGamelist()
{
	swprintf(commonChoice, L"gamelist.ini");
	if (commonFileDialog(hScrnWnd, true, localiseStringEx(IDS_GAMELIST_CREATE), L"Gamelist file (*.ini)\0*.ini\0\0", L"lang", L"ini")) {
		return 1;
	}
	return createGamelistFile(commonChoice);
}

static const wchar_t* getTranslateGameName(string key)
{
	static wstring name;
	map<string, wstring>::iterator iter = gamelistMap.find(key);
	if (iter != gamelistMap.end()) {
		name = iter->second;
		return name.c_str();
	}
	return NULL;
}

const wchar_t* transGameName(const char* oldName, unsigned index)
{
	if (!oldName) {
		return NULL;
	}

	static wchar_t newName[MAX_PATH] = L"";

	if ((loadMenuShowX & TRANSLANG) == 0) {
		swprintf(newName, L"%hs", oldName);
		return newName;
	}

	if (!gamelistLoaded) {
		initGamelist();
	}

	const wchar_t* gameName = getTranslateGameName(BurnDrvGetTextA(DRV_NAME, index));
	if (gameName) {
		return gameName;
	}

	swprintf(newName, L"%hs", oldName);
	return newName;
}
/* end Sho, thanks 800 */
